--[[ more safely release and destroy squad NPC by switching it offline first author: Alundaio I don't know why but for some unknown amount of frames after se_obj releases, object binder still exists. Can lead to undefined behavior where server object is nil but game object isn't. This is my solution: switch the object offline to force a net_destroy, then release. Maybe the reason is the excessive usage of db.storage[id].object instead of level.object_by_id(id)??? Also, this appears to be a safe way to release online_offline_group (squad) objects. --]] local objects_to_release = {} --------------------------------------------------------------- -- register object to be released safely function release(se_obj) objects_to_release[se_obj.id] = true end --------------------------------------------------------------- function execute_destroy_callback() if not (is_empty(objects_to_release)) then local sim = alife() for id,v in pairs(objects_to_release) do local se_obj = alife_object(id) if (se_obj) then if (se_obj.online) then -- prevent from coming online ever again sim:set_switch_online(id,false) sim:set_switch_offline(id,true) -- force offline --if (se_obj:can_switch_offline()) then se_obj:switch_offline() --else -- printf("Warning: Can't switch offline %s",se_obj:name()) -- end --printf("% safe_release_manager | switch offline: %s (%s)", se_obj:name(), id) else -- binder has not been destroyed yet...or error local obj = db.storage[id] and db.storage[id].object if not (obj) then --printf("% safe_release_manager | release %s (%s)", se_obj:name(), id) alife_record(se_obj,false) sim:release(se_obj,true) objects_to_release[id] = nil end end end end end return false end --------------------------------------------------------------- local function actor_on_reinit(binder) objects_to_release = alife_storage_manager.get_state().objects_to_release or objects_to_release AddUniqueCall(execute_destroy_callback) end ---------------------------------------------------------------- -- ON_GAME_START ---------------------------------------------------------------- function on_game_start() RegisterScriptCallback("actor_on_reinit",actor_on_reinit) end